home *** CD-ROM | disk | FTP | other *** search
- /*
- YacTris v0.0
- Copyright ⌐1993 Jonathan P. Springer
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- For more details see the files README and COPYING, which should have
- been included in this distribution.
-
- The author can be reached during the school year at these E-Mail addresses:
-
- springjp@screech.alfred.edu (Internet)
- springjp@ceramics.bitnet (Bitnet)
-
- And can be reached by paper mail year-round at the following address:
-
- Jonathan Springer
- 360 W. Main St.
- Dallastown, PA 17313-2014
- USA
-
- */
-
-
- /*
- **
- ** yactris.c
- **
- ** The definitive Tetris for AmigaDOS 2.0
- **
- ** Jonathan Springer
- **
- ** v 0.0
- **
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/ports.h>
- #include <dos/dos.h>
- #include <graphics/displayinfo.h>
- #include <graphics/gfxmacros.h>
- #include <intuition/intuition.h>
- #include <intuition/screens.h>
- #include <libraries/gadtools.h>
- #include <utility/tagitem.h>
- #include <workbench/startup.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <dbug.h>
- #include "yactris.h"
- #include <bruce.h>
-
- /****************/
- /* Prototypes */
- /****************/
-
- #include <clib/dos_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/icon_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/gadtools_protos.h>
- #include <clib/layers_protos.h>
-
- Prototype void TStartUp(void);
- Prototype void Tetris(void);
- Prototype struct PieceRot *PickPiece(void);
- Prototype void ClearPlayField(void);
- Prototype BOOL NewPiece(struct PieceRot *, int, int);
- Prototype BOOL MovePiece(enum direction);
- Prototype BOOL RotatePiece(void);
- Prototype void ByeBye(int);
- Prototype void PlacePiece(void);
- Prototype BOOL GameOver(void);
- Prototype void ResetTet(void);
- Prototype void FillInTWindow(struct Window *, struct ScreenInfo *);
- Prototype BOOL IsHitting(struct PieceRot *, int, int);
- Prototype void DoNewPubScreen(struct Screen *news);
- Prototype BOOL VerifyQuit(void);
- Prototype int NoBreak(void);
-
- enum direction {left, down, right, null};
-
- /***********************/
- /* Piece Definitions */
- /***********************/
-
- const UBYTE Multi[] =
- /* 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 */
-
- { 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1 };
-
- extern struct MakeStruct LineM0[], LineM1[], BlockM[], TeeM0[], TeeM1[],
- TeeM2[], TeeM3[], ZigM0[], ZigM1[], ZagM0[], ZagM1[], EllM0[], EllM1[],
- EllM2[], EllM3[], LeeM0[], LeeM1[], LeeM2[], LeeM3[];
-
- struct PieceRot Line[2] = {
- { LINE, &Line[1], {0}, 4, 1, &Multi[4], LineM0 },
- { LINE, Line, {0}, 1, 4, &Multi[4], LineM1 }
- };
-
- struct PieceRot Block = { BLOCK, &Block, {0}, 2, 2, &Multi[4], BlockM };
-
- struct PieceRot Tee[4] = {
- { TEE, &Tee[1], {0}, 3, 2, &Multi[9], TeeM0 },
- { TEE, &Tee[2], {0}, 2, 3, &Multi[10], TeeM1 },
- { TEE, &Tee[3], {0}, 3, 2, &Multi[12], TeeM2 },
- { TEE, Tee, {0}, 2, 3, &Multi[11], TeeM3 }
- };
-
- struct PieceRot Zig[2] = {
- { ZIG, &Zig[1], {0}, 3, 2, Multi, ZigM0 },
- { ZIG, Zig, {0}, 2, 3, &Multi[3], ZigM1 }
- };
-
- struct PieceRot Zag[2] = {
- { ZAG, &Zag[1], {0}, 3, 2, &Multi[3], ZagM0 },
- { ZAG, Zag, {0}, 2, 3, &Multi[16], ZagM1 }
- };
-
- struct PieceRot Ell[4] = {
- { ELL, &Ell[1], {0}, 3, 2, &Multi[2], EllM0 },
- { ELL, &Ell[2], {0}, 2, 3, &Multi[14], EllM1 },
- { ELL, &Ell[3], {0}, 3, 2, &Multi[4], EllM2 },
- { ELL, Ell, {0}, 2, 3, &Multi[13], EllM3 }
- };
-
- struct PieceRot Lee[4] = {
- { LEE, &Lee[1], {0}, 3, 2, &Multi[1], LeeM0 },
- { LEE, &Lee[2], {0}, 2, 3, &Multi[12], LeeM1 },
- { LEE, &Lee[3], {0}, 3, 2, &Multi[5], LeeM2 },
- { LEE, Lee, {0}, 2, 3, &Multi[9], LeeM3 }
- };
-
- struct BitMap Sqbm = {0};
-
- struct PieceRot *Pieces[NUM_TYPES] = { Line, &Block, Tee, Zig, Zag, Ell, Lee };
- int PieceCount[NUM_TYPES] = {0};
-
- /**********************/
- /* Menu Definitions */
- /**********************/
-
- struct NewMenu tNewMenu[] = {
- { NM_TITLE, "Game", 0 , 0, 0, 0 },
- { NM_ITEM, "Start", "S", 0, 0, 0 },
- { NM_ITEM, "Halt", "H", 0, 0, 0 },
- { NM_ITEM, "Reset", "R", 0, 0, 0 },
- { NM_ITEM, NM_BARLABEL, 0 , 0, 0, 0 },
- { NM_ITEM, "About...", "?", 0, 0, 0 },
- { NM_ITEM, NM_BARLABEL, 0 , 0, 0, 0 },
- { NM_ITEM, "Quit...", "Q", 0, 0, 0 },
- { NM_TITLE, "Display", 0 , 0, 0, 0 },
- { NM_ITEM, "Show Next", 0 , CHECKIT|CHECKED|MENUTOGGLE, 0, 0},
- { NM_ITEM, "Show Piece Count", 0, CHECKIT|MENUTOGGLE, 0, 0},
- { NM_ITEM, NM_BARLABEL, 0 , 0, 0, 0 },
- { NM_ITEM, "New Screen...","P", 0, 0, 0 },
- { NM_END, NULL, 0 , 0, 0, 0 }
- };
-
- /***********************/
- /* The Playing Field */
- /***********************/
- UBYTE Field[FWIDTH][FHEIGHT] = {0};
-
- /***************/
- /* The Piece */
- /***************/
- struct PieceRot *Piece=NULL, *Next=NULL;
- int Px, Py;
-
- /***************/
- /* The Score */
- /***************/
-
- int StartLev = 0;
- const int CapLev = 11;
- int Level;
- int Lines = 0;
- int Score = 0;
- int Lin2Inc = 10;
- BOOL ShowNext = TRUE;
-
- char *StartScreen = NULL;
- char ss[MAXPUBSCREENNAME];
-
- /***********************/
- /* System Structures */
- /***********************/
-
- struct Window *tWindow = NULL;
- struct Window *pWindow = NULL;
- struct Screen *tScreen = NULL;
- struct Menu *tMenus = NULL;
- struct ScreenInfo *ScrInfo = NULL;
-
- struct Library *IconBase;
-
- int NoBreak(void) { return 0; }
-
- /*
- ** main()
- */
-
- int main (int argc, char **argv) {
-
- int i;
-
- #ifndef DBUG_OFF
- #define ARGS 4
- char template[] = "STARTLEVEL/K/N, LINESTOINC/K/N, PUBSCREEN/K, D=DBUG/K/F";
- #else
- #define ARGS 3
- char template[] = "STARTLEVEL/K/N, LINESTOINC/K/N, PUBSCREEN/K";
- #endif
-
- ULONG argout[ARGS] = {0};
- struct RDArgs *rda = NULL;
-
- DBUG_ENTER("main");
-
- #ifdef DBUG_OFF
- onbreak(NoBreak);
- #endif
-
- DBUG_PROCESS(argv[0]);
-
- if (rda=ReadArgs(template, argout, NULL)) {
-
- if (argout[0]) StartLev = *( (LONG *) argout[0]);
-
- if (argout[1]) Lin2Inc = *( (LONG *) argout[1]);
-
- if (argout[2]) StartScreen = strcpy(ss, (char *) argout[2]);
-
- #ifndef DBUG_OFF
- if (argout[3]) DBUG_PUSH( (char *) argout[2] );
- #endif
-
- }
-
- if (rda) FreeArgs(rda);
-
- TStartUp();
-
- exit(0);
-
- DBUG_RETURN(0);
- }
-
- /*
- ** wbmain()
- */
- int wbmain(struct WBStartup *wbs)
- {
- struct DiskObject *dobj = NULL;
- char *tstr;
- BPTR olddir = -1;
-
- DBUG_ENTER("wbmain");
-
- DBUG_PROCESS(wbs->sm_ArgList->wa_Name);
-
- if (IconBase = OpenLibrary("icon.library",33)) {
-
- if (wbs->sm_ArgList->wa_Lock)
- olddir = CurrentDir(wbs->sm_ArgList->wa_Lock);
-
- if (dobj=GetDiskObject(wbs->sm_ArgList->wa_Name)) {
-
- if (tstr = FindToolType(dobj->do_ToolTypes, "STARTLEVEL"))
- StartLev = atoi(tstr);
-
- if (tstr = FindToolType(dobj->do_ToolTypes, "LINESTOINC"))
- Lin2Inc = atoi(tstr);
-
- if (tstr = FindToolType(dobj->do_ToolTypes, "PUBSCREEN"))
- StartScreen = strcpy(ss, tstr);
-
- #ifndef DBUG_OFF
- if (tstr = FindToolType(dobj->do_ToolTypes, "DBUG"))
- DBUG_PUSH(tstr);
- #endif
-
- FreeDiskObject(dobj);
-
- }
-
- if (olddir != -1) CurrentDir(olddir);
-
- }
-
- TStartUp();
-
- if (IconBase) CloseLibrary(IconBase);
-
- exit(0);
-
- DBUG_RETURN(0);
- }
-
- /*
- **
- ** TStartUp()
- **
- ** Start up and Tetrisize
- **
- */
- void TStartUp(void)
- {
- struct Screen *tScreen;
-
- DBUG_ENTER("TStartUp");
-
- srand(time(NULL));
-
- if (!(tScreen = LockPubScreen(StartScreen)))
- tScreen = LockPubScreen(NULL);
-
- if (ScrInfo = CreateScrInfo(tScreen)) {
-
- /* Construct the Menus */
- if (tMenus = CreateMenus(tNewMenu, TAG_DONE)) {
-
- if (LayoutMenus(tMenus, ScrInfo->vi, TAG_DONE)) {
-
- /* Open the Windows */
- if (tWindow=OpenTWindow(ScrInfo, tMenus)) {
-
- /* Make the Pieces */
- if (MakePieces(ScrInfo)) {
-
- ResetTet();
-
- /* Do the Tetris thing */
- Tetris();
-
- }
-
- UnMakePieces(ScrInfo);
-
- }
- }
- }
- }
-
- /* Clean Up */
- if (pWindow) ClosePWindow(pWindow);
- if (tWindow) CloseTWindow(tWindow);
- if (tMenus) FreeMenus(tMenus);
- if (ScrInfo) {
- if (ScrInfo->s) UnlockPubScreen(NULL, ScrInfo->s);
- FreeScrInfo(ScrInfo);
- }
-
- DBUG_VOID_RETURN;
- }
-
- /*
- **
- ** Tetris()
- **
- ** Do the actual Tetrising
- **
- */
-
- void Tetris(void)
- {
- int tickstodrop = CapLev - Level;
- BOOL active = FALSE, hitting = FALSE, over = FALSE;
- BOOL breakmenloop = FALSE;
- int tickcount = 0;
- struct IntuiMessage *inMsg;
- int i;
-
- UWORD Code;
- ULONG Class;
- ULONG signals;
- struct Window *IWindow;
-
- struct Screen *news;
-
- DBUG_ENTER("Tetris");
-
- FlagWindow(tWindow, FALSE);
-
- while (!over) {
- signals = Wait(1L << tWindow->UserPort->mp_SigBit);
- while ((!over) &&
- (inMsg = (struct IntuiMessage *) GetMsg(tWindow->UserPort))
- ) {
- Code = inMsg->Code;
- Class = inMsg->Class;
- IWindow = inMsg->IDCMPWindow;
- ReplyMsg( (struct Message *) inMsg);
- switch(Class) {
-
- case IDCMP_MENUPICK:
- DBUG_PRINT("Tetris",("PickMenu received"));
- breakmenloop = FALSE;
- while (Code != MENUNULL) {
-
- switch (MENUNUM(Code)) {
-
- case 0:
- if (ITEMNUM(Code)!=NOITEM) switch (ITEMNUM(Code)) {
-
- case 0:
- active = TRUE;
- FlagWindow(tWindow, TRUE);
- break;
- case 1:
- active = FALSE;
- FlagWindow(tWindow, FALSE);
- break;
- case 2:
- ResetTet();
- active = FALSE;
- FlagWindow(tWindow, FALSE);
- tickcount = 0;
- tickstodrop = CapLev-Level;
- hitting = FALSE;
- break;
- case 4:
- DoAbout(ScrInfo);
- break;
- case 6:
- if (VerifyQuit()) breakmenloop = over = TRUE;
- break;
- default:
- break;
-
- }
- break;
-
- case 1:
- if (ITEMNUM(Code)!=NOITEM) switch (ITEMNUM(Code)) {
-
- case 0:
- if (ItemAddress(tMenus, Code)->Flags & CHECKED) {
- if (!ShowNext) ShowNext = TRUE;
- BltBitMapRastPort(&Next->BitMap, 0, 0,
- tWindow->RPort,
- ScrInfo->NPLeft, ScrInfo->NPTop,
- 4*ScrInfo->xTimes, 4*ScrInfo->yTimes, 0xc0);
- } else if (ShowNext) {
- ShowNext = FALSE;
- EraseRect(tWindow->RPort,
- ScrInfo->NPLeft, ScrInfo->NPTop,
- ScrInfo->NPLeft+4*ScrInfo->xTimes-1,
- ScrInfo->NPTop+4*ScrInfo->yTimes-1);
- }
- break;
-
- case 1:
- if (ItemAddress(tMenus, Code)->Flags & CHECKED) {
- if (!pWindow) {
- if (pWindow =
- OpenPWindow(ScrInfo, tWindow->UserPort
- )) {
- for (i=0; i<NUM_TYPES; i++)
- DispPCount(ScrInfo, pWindow,
- Pieces[i], PieceCount[i]);
- } else {
- ClearMenuStrip(tWindow);
- ItemAddress(tMenus, Code)->Flags &=
- ~CHECKED;
- ResetMenuStrip(tWindow, tMenus);
- }
- }
- } else if (pWindow) {
- ClosePWindow(pWindow);
- pWindow = NULL;
- }
- break;
-
- case 3:
- if (news = InquirePubScreen(ScrInfo)) {
- DBUG_PRINT("Tetris",("Opening new window, Screen Address %p",news));
- DoNewPubScreen(news);
- active = FALSE;
- FlagWindow(tWindow, FALSE);
- tickcount = 0;
- BltBitMapRastPort(&Piece->BitMap,0,0,
- tWindow->RPort,
- ScrInfo->FieldInLeft + Px * ScrInfo->xTimes,
- ScrInfo->FieldInTop + Py * ScrInfo->yTimes,
- Piece->width * ScrInfo->xTimes,
- Piece->height * ScrInfo->yTimes, 0x60);
- hitting = IsHitting(Piece, Px, Py);
- UpdateScores(tWindow, ScrInfo, Level, Score, Lines);
- breakmenloop = TRUE;
- }
-
- default:
- break;
-
- }
-
- default:
- break;
-
- }
-
- if (breakmenloop) Code = MENUNULL;
- else Code = ItemAddress(tMenus, Code)->NextSelect;
- }
-
- break;
-
- case IDCMP_CLOSEWINDOW:
- DBUG_PRINT("Tetris",("CloseWindow received"));
- if (IWindow == tWindow) {
- over = TRUE;
- } else if (IWindow == pWindow && pWindow) {
- ClosePWindow(pWindow);
- pWindow = NULL;
- ClearMenuStrip(tWindow);
- ItemAddress(tMenus, FULLMENUNUM(1,1,NOSUB))->Flags &=
- ~CHECKED;
- ResetMenuStrip(tWindow, tMenus);
- }
- break;
-
- case IDCMP_INTUITICKS:
- if (!(tickcount = ++tickcount % tickstodrop)) {
- if (!hitting)
- hitting=MovePiece(down);
- else {
- PlacePiece();
- if (NewPiece(PickPiece(),STARTX,STARTY)) {
- active=FALSE;
- if (!( over = GameOver() )) ResetTet();
- FlagWindow(tWindow, FALSE);
- }
- hitting = FALSE;
- tickcount = 0;
- tickstodrop = CapLev - Level;
- }
- }
- break;
-
- case IDCMP_VANILLAKEY:
- switch (Code) {
-
- case '4':
- hitting=MovePiece(left);
- break;
- case '6':
- hitting=MovePiece(right);
- break;
- case '2':
- if (!hitting)
- hitting=MovePiece(down);
- else {
- PlacePiece();
- if (NewPiece(PickPiece(),STARTX,STARTY)) {
- active=FALSE;
- if (!( over = GameOver() )) ResetTet();
- FlagWindow(tWindow, FALSE);
- }
- hitting = FALSE;
- tickcount = 0;
- tickstodrop = CapLev - Level;
- }
- break;
- case '5':
- hitting=RotatePiece();
- break;
- default:
- break;
- }
- break;
-
- default:
- break;
- }
- }
- }
-
- DBUG_VOID_RETURN;
- }
-
- /*
- **
- ** PickPiece()
- **
- ** Pick a piece to fall next
- **
- */
-
- struct PieceRot *PickPiece(void)
- {
- struct PieceRot *p;
-
- DBUG_ENTER("PickPiece");
-
- if (!Next) Next = Pieces[rand()%NUM_TYPES];
-
- p = Next;
- Next = Pieces[rand() % NUM_TYPES];
-
- if (ShowNext) BltBitMapRastPort(&Next->BitMap, 0, 0,tWindow->RPort,
- ScrInfo->NPLeft, ScrInfo->NPTop, 4*ScrInfo->xTimes, 4*ScrInfo->yTimes,
- 0xc0);
-
- DBUG_RETURN(p);
- }
-
- /*
- **
- ** ClearPlayField()
- **
- ** Clear the playfield array and clear the window display
- **
- */
-
- void ClearPlayField(void)
- {
- int i, j;
-
- DBUG_ENTER("ClearPlayField");
-
- for (i=0; i<FHEIGHT; i++)
- for (j=0; j<FWIDTH; j++)
- Field[j][i] = 0;
-
- EraseRect(tWindow->RPort, ScrInfo->FieldInLeft, ScrInfo->FieldInTop,
- ScrInfo->FieldInLeft + ScrInfo->FieldInWidth - 1,
- ScrInfo->FieldInTop + ScrInfo->FieldInHeight - 1);
-
- DBUG_VOID_RETURN;
- }
-
- /*
- **
- ** NewPiece()
- **
- ** Set up and display a new piece
- **
- */
- BOOL NewPiece(struct PieceRot *p, int x, int y)
- {
- BOOL loser=FALSE;
- int i,j;
-
- DBUG_ENTER("NewPiece");
-
- Piece = p;
- Px = x;
- Py = y;
-
-
- for (i=0; i<Piece->width && !loser; i++)
- for (j=0; j<Piece->height && !loser; j++)
- if (Piece->map[j*Piece->width+i] && Field[Px+i][Py+j]) loser=TRUE;
-
- BltBitMapRastPort(&Piece->BitMap,0,0, tWindow->RPort,
- ScrInfo->FieldInLeft + Px * ScrInfo->xTimes,
- ScrInfo->FieldInTop + Py * ScrInfo->yTimes,
- Piece->width * ScrInfo->xTimes, Piece->height * ScrInfo->yTimes, 0x60);
-
- PieceCount[p->type]++;
- if (pWindow)
- DispPCount(ScrInfo, pWindow, Pieces[p->type], PieceCount[p->type]);
-
- DBUG_PRINT("NP",("List drawn, loser = %d",loser));
-
- DBUG_RETURN(loser);
- }
-
- /*
- **
- ** PlacePiece()
- **
- ** Add the piece to the playfield
- **
- */
-
- void PlacePiece(void) {
-
- int i,j,k;
- int numlines;
- int lines[4];
- int add2score = 1;
-
- DBUG_ENTER("PlacePiece");
-
- /* Add the piece to the playfield array */
- for (i=0; i<Piece->height; i++)
- for (j=0; j<Piece->width; j++)
- if (Piece->map[i*Piece->width+j]) Field[Px+j][Py+i] = 1;
-
- /* Increment the score */
- Score++;
-
- /* And check to see if any lines are complete */
- for (j=Py+Piece->height-1, numlines=0; j>=Py; j--) {
- for (i=0; i<FWIDTH && Field[i][j]; i++);
- if (i==FWIDTH) {
- lines[numlines]=j;
- DBUG_PRINT("PP",("Line %d filled.", lines[numlines]));
- numlines++;
- }
- }
-
- /* If lines have been completed */
- if (numlines) {
-
- /* Do the graphics ... */
- for (i=0; i<numlines; i++) {
- DBUG_PRINT("PP",("Reversing line %d", lines[i]));
- BltBitMapRastPort(tWindow->RPort->BitMap,0,0,tWindow->RPort,
- ScrInfo->FieldInLeft,
- ScrInfo->FieldInTop + lines[i]*ScrInfo->yTimes,
- ScrInfo->xTimes * FWIDTH, ScrInfo->yTimes, 0x50);
- }
-
- /* The array ... */
- for (i=numlines-1; i>=0; i--) {
- DBUG_PRINT("PP",("Cleaning array for line %d", lines[i]));
- for (k=lines[i]; k>0; k--)
- for (j=0; j<FWIDTH; j++)
- Field[j][k]=Field[j][k-1];
- for (j=0; j<FWIDTH; j++)
- Field[i][0] = 0;
- }
-
- /* More graphics ... */
- for (i=numlines-1; i>=0; i--) {
- DBUG_PRINT("PP",("Scrolling over line %d", lines[i]));
- for (j=0; j<ScrInfo->yTimes; j++)
- ScrollRaster(tWindow->RPort, 0, -1,
- ScrInfo->FieldInLeft, ScrInfo->FieldInTop,
- ScrInfo->FieldInLeft+FWIDTH*ScrInfo->xTimes-1,
- ScrInfo->FieldInTop+lines[i]*ScrInfo->yTimes+j);
- }
-
- /* And increment the score properly */
- for (i=0; i<numlines; i++) add2score *=10;
- Score += add2score;
- Lines += numlines;
- if ( (Lines>=(Level-StartLev+1)*Lin2Inc) && (Level<CapLev-1)) Level++;
- }
-
- UpdateScores(tWindow, ScrInfo, Level, Score, Lines);
-
- DBUG_VOID_RETURN;
- }
-
- /*
- **
- ** MovePiece()
- **
- ** Move the Bob to the new location, and return whether it's hitting
- **
- */
-
- BOOL MovePiece(enum direction dir)
- {
- BOOL legal = TRUE, hitting = FALSE;
- int i, j;
-
- DBUG_ENTER("MovePiece");
-
- /* Check the legality of the move */
- switch (dir) {
-
- case down:
- if (Py + Piece->height == FHEIGHT) legal=FALSE;
- for (i=0; i < Piece->width && legal; i++)
- for (j= Piece->height - 1; j >= 0; j--)
- if (Piece->map[ j * Piece->width + i]) {
- if (Py+j+1 >= FHEIGHT) legal=FALSE;
- else if (Field[Px+i][Py+j+1]) legal=FALSE;
- break;
- }
- break;
-
- case left:
- if (Px == 0) legal=FALSE;
- for (j=0; j < Piece->height && legal; j++)
- for (i=0; i < Piece->width; i++)
- if (Piece->map[ j * Piece->width + i]) {
- if (Px+i <= 0) legal=FALSE;
- else if (Field[Px+i-1][Py+j]) legal=FALSE;
- break;
- }
- break;
-
- case right:
- if (Px + Piece->width == FWIDTH) legal=FALSE;
- for (j=0; j < Piece->height && legal; j++)
- for (i = Piece->width - 1; i >= 0; i--)
- if (Piece->map[ j * Piece->width + i]) {
- if (Px+i+1 >= FHEIGHT) legal=FALSE;
- else if (Field[Px+i+1][Py+j]) legal=FALSE;
- break;
- }
- break;
-
- default:
- break;
-
- }
-
- if (legal) {
-
- /* Remove the old image */
- BltBitMapRastPort(&Piece->BitMap,0,0,tWindow->RPort,
- ScrInfo->FieldInLeft+ScrInfo->xTimes*Px,
- ScrInfo->FieldInTop+ScrInfo->yTimes*Py,
- Piece->width*ScrInfo->xTimes, Piece->height*ScrInfo->yTimes,
- 0x20);
-
- switch (dir) {
- case down: Py++; break;
- case left: Px--; break;
- case right: Px++; break;
- default: break;
- }
-
- /* And display the new one */
- BltBitMapRastPort(&Piece->BitMap,0,0,tWindow->RPort,
- ScrInfo->FieldInLeft+ScrInfo->xTimes*Px,
- ScrInfo->FieldInTop+ScrInfo->yTimes*Py,
- Piece->width*ScrInfo->xTimes, Piece->height*ScrInfo->yTimes,
- 0x60);
-
- }
-
- hitting = IsHitting(Piece, Px, Py);
-
- DBUG_PRINT("MP",("Piece Moved, hitting=%d",hitting));
-
- DBUG_RETURN(hitting);
- }
-
- /*
- **
- ** PieceRot()
- **
- ** Rotate the piece 1/4 turn clockwise
- **
- */
- BOOL RotatePiece(void)
- {
- struct PieceRot *np;
- int nx, ny;
- int i, j;
- BOOL legal = TRUE, hitting = FALSE;
-
- DBUG_ENTER("RotatePiece");
-
- np = Piece->next;
- nx = Px;
- ny = Py;
-
- while (nx + np->width > FWIDTH) nx--;
-
- if (ny + np->height > FHEIGHT) legal = FALSE;
- else for (i=0; i < np->width && legal; i++)
- for (j = np->height - 1; j >= 0; j--)
- if (np->map[j * np->width + i] && Field[nx+i][ny+j]) {
- legal=FALSE;
- break;
- }
-
- if (legal) {
- /* Remove the old piece */
- BltBitMapRastPort(&Piece->BitMap,0,0,tWindow->RPort,
- ScrInfo->FieldInLeft+ScrInfo->xTimes*Px,
- ScrInfo->FieldInTop+ScrInfo->yTimes*Py,
- Piece->width*ScrInfo->xTimes, Piece->height*ScrInfo->yTimes,
- 0x20);
-
- /* Change some things */
- Px = nx;
- Py = ny;
- Piece = np;
-
- /* And display the new piece */
- BltBitMapRastPort(&Piece->BitMap,0,0,tWindow->RPort,
- ScrInfo->FieldInLeft+ScrInfo->xTimes*Px,
- ScrInfo->FieldInTop+ScrInfo->yTimes*Py,
- Piece->width*ScrInfo->xTimes, Piece->height*ScrInfo->yTimes,
- 0x60);
-
- }
-
- hitting = IsHitting(Piece, Px, Py);
-
- DBUG_RETURN(hitting);
- }
-
- /*
- **
- ** ByeBye()
- **
- */
-
- void ByeBye(int back)
- {
- DBUG_ENTER("ByeBye");
-
- DBUG_PRINT("Bye",("Emergency Exit: Code %d", back));
-
- exit (back);
-
- DBUG_VOID_RETURN;
- }
-
- /*
- **
- ** GameOver()
- **
- ** Display the "Game Over" requester and ask if the user wants to play again.
- **
- */
- BOOL GameOver(void)
- {
- struct EasyStruct es = {
- sizeof(struct EasyStruct),
- 0,
- "YacTris",
- "\nGame Over\n\nFinal Score: %ld\nLines Cleared: %ld\n\nPlay Again?\n",
- "Yes|No"
- };
-
- int over;
-
- DBUG_ENTER("GameOver");
-
- over = !(EasyRequest(tWindow, &es, NULL, (APTR) Score, Lines));
-
- DBUG_RETURN(over);
- }
-
- /*
- **
- ** ResetTet()
- **
- ** Reset everything for a new game.
- **
- */
- void ResetTet(void)
- {
- int i;
-
- DBUG_ENTER("ResetTet");
-
- ClearPlayField();
- Score = Lines = 0;
- Level = StartLev;
- UpdateScores(tWindow, ScrInfo, Level, Score, Lines);
- for (i=0; i<NUM_TYPES; i++) PieceCount[i] = 0;
- if (pWindow) for (i=0; i<NUM_TYPES; i++)
- DispPCount(ScrInfo, pWindow, Pieces[i], 0);
- NewPiece( PickPiece(), STARTX, STARTY);
-
- DBUG_VOID_RETURN;
- }
-
- /*
- ** FillInTWindow
- **
- ** Recolor the proper blocks.
- **
- */
- void FillInTWindow(struct Window *tw, struct ScreenInfo *si)
- {
- int i,j;
- PLANEPTR tr;
- struct TmpRas TR;
- const UWORD fill = 0xffff;
-
- DBUG_ENTER("FillInTWindow");
-
- SetAfPt(tw->RPort, &fill, 0);
-
- for (i=0; i<FWIDTH; i++)
- for (j=0; j<FHEIGHT; j++)
- if (Field[i][j])
- BltBitMapRastPort(&Sqbm, 0, 0, tw->RPort,
- si->FieldInLeft + i*si->xTimes,
- si->FieldInTop + j*si->yTimes,
- si->xTimes, si->yTimes,
- 0x60);
-
- DBUG_VOID_RETURN;
- }
-
-
- /*
- **
- ** IsHitting()
- **
- ** Returns TRUE if a piece is resting on a piece below it.
- **
- */
- BOOL IsHitting(struct PieceRot *p, int x, int y)
- {
- int i,j;
- BOOL hitting = FALSE;
-
- DBUG_ENTER("IsHitting");
-
- for (i=0; i<p->width && !hitting; i++)
- for (j=p->height-1; j>=0; j--)
- if (p->map[j*p->width+i]) {
- hitting = (BOOL)((y+j+1==FHEIGHT) || (Field[x+i][y+j+1]));
- break;
- }
-
- DBUG_RETURN(hitting);
- }
-
- /*
- **
- ** DoNewPubScreen
- **
- ** Open the YacTris window on a new screen.
- **
- */
- void DoNewPubScreen(struct Screen *news)
- {
- struct ScreenInfo *si = NULL;
- struct Window *tw = NULL;
- struct Window *pw = NULL;
- struct Menu *tm = NULL;
-
- BOOL success = FALSE;
-
- int i;
-
- DBUG_ENTER("OpenNewPubScreen");
-
- if (si = CreateScrInfo(news)) {
- if (tm = CreateMenus(tNewMenu, TAG_END)) {
- if (LayoutMenus(tm, si->vi, TAG_END)) {
- if (tw=OpenTWindow(si, tm)) {
- MakePieces(si);
- FillInTWindow(tw, si);
- if (ShowNext) {
- BltBitMapRastPort(&Next->BitMap, 0, 0,
- tw->RPort, si->NPLeft, si->NPTop,
- 4*si->xTimes, 4*si->yTimes, 0xc0);
- } else {
- ClearMenuStrip(tw);
- ItemAddress(tm, FULLMENUNUM(1,0,NOSUB))->Flags
- &= ~CHECKED;
- ResetMenuStrip(tw,tm);
- }
- if (pWindow) {
- if (pw=OpenPWindow(si, tw->UserPort)) {
- for (i=0; i<NUM_TYPES; i++)
- DispPCount(si, pw, Pieces[i], PieceCount[i]);
- ClearMenuStrip(tw);
- ItemAddress(tm, FULLMENUNUM(1,1,NOSUB))->Flags
- |= CHECKED;
- ResetMenuStrip(tw, tm);
- } else {
- ClearMenuStrip(tw);
- ItemAddress(tm, FULLMENUNUM(1,1,NOSUB))->Flags
- &= ~CHECKED;
- ResetMenuStrip(tw, tm);
- }
- } else {
- pw = NULL;
- ClearMenuStrip(tw);
- ItemAddress(tm, FULLMENUNUM(1,1,NOSUB))->Flags
- &= ~CHECKED;
- ResetMenuStrip(tw, tm);
- }
-
- if (pWindow) ClosePWindow(pWindow);
- pWindow = pw;
-
- CloseTWindow(tWindow);
- tWindow = tw;
-
- FreeMenus(tMenus);
- tMenus = tm;
-
- UnlockPubScreen (NULL, ScrInfo->s);
- FreeScrInfo(ScrInfo);
- ScrInfo = si;
-
- tScreen = news;
-
- success = TRUE;
- }
- }
- }
- }
-
- if (!success) {
- if (pw) ClosePWindow(pw);
- if (tw) CloseTWindow(tw);
- if (tm) FreeMenus(tm);
- if (si) FreeScrInfo(si);
- }
-
- DBUG_VOID_RETURN;
-
- }
-
- /*
- **
- ** VerifyQuit
- **
- ** Check to be sure the user really wants to quit.
- **
- */
- BOOL VerifyQuit(void)
- {
- struct EasyStruct es = {
- sizeof(struct EasyStruct),
- 0,
- "YacTris Request",
- "Final Score: %ld\nLines Cleared: %ld\n\nReally Quit?\n",
- "Yes|No"
- };
-
- int ret;
-
- DBUG_ENTER("VerifyQuit");
-
- ret = EasyRequest(tWindow, &es, NULL, (APTR) Score, Lines);
-
- DBUG_RETURN(ret);
- }
-
-